package com.grapes.business;

import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.grapes.model.CampusTalking;
import com.grapes.model.DailyInfo;
import com.grapes.model.NetApplication;
import com.grapes.model.RecruiteInfo;

public class ProcedureBusiness {
	public static final int PROCEDURE_REFUSED = 1;
	public static final int PROCEDURE_APPLICATED = 2;
	public static final int PROCEDURE_STORED = 3;

	// 10 minutes
	private final long MIN_PROCEDURE_REFRESH_INTERVAL = 1000 * 60 * 10;
	private long lastGetRefusedProceduresTime = -1;
	private long lastGetStoredProceduresTime = -1;
	private long lastGetApplicatedProceduresTime = -1;

	private List<RecruiteInfo> cachedRefusedProcedures;
	private List<RecruiteInfo> cachedStoredProcedures;
	private List<RecruiteInfo> cachedApplicatedProcedures;

	private static ProcedureBusiness instance;

	private ProcedureBusiness() {
	};

	public static ProcedureBusiness getInstance() {
		if (null == instance) {
			instance = new ProcedureBusiness();
		}
		return instance;
	}

	public List<RecruiteInfo> getProcedures(int procedureType, String renrenId,
			int page) throws JSONException {
		long currentTime = System.currentTimeMillis();

		switch (procedureType) {
		case PROCEDURE_REFUSED:
			if (currentTime - lastGetRefusedProceduresTime < MIN_PROCEDURE_REFRESH_INTERVAL)
				return cachedRefusedProcedures;
			break;
		case PROCEDURE_APPLICATED:
			if (currentTime - lastGetApplicatedProceduresTime < MIN_PROCEDURE_REFRESH_INTERVAL)
				return cachedApplicatedProcedures;
			break;
		case PROCEDURE_STORED:
			if (currentTime - lastGetStoredProceduresTime < MIN_PROCEDURE_REFRESH_INTERVAL)
				return cachedStoredProcedures;
			break;
		}

		Map<String, String> params = new HashMap<String, String>();
		params.put("renrenId", renrenId);
		params.put("page", String.valueOf(page));
		String result = Connection.getInstance().executeHttpGet(
				Connection.BIZ_GET_PERSONAL_ACTIVITY_LIST, params);
		JSONObject jObj = new JSONObject(result);
		String retCode = jObj.getString("ret_code");
		if (Connection.RESULT_CODE_FAIL == Integer.valueOf(retCode).intValue())
			throw (new JSONException("retCode error"));
		JSONArray jsonArray = jObj.getJSONArray("activities");
		parseJSONActivities(jsonArray, procedureType);
		switch (procedureType) {
		case PROCEDURE_REFUSED:
			return cachedRefusedProcedures;
		case PROCEDURE_APPLICATED:
			return cachedApplicatedProcedures;
		case PROCEDURE_STORED:
			return cachedStoredProcedures;
		default:
			return null;
		}
	}

	private void parseJSONActivities(JSONArray jsonArray, int procedureType)
			throws JSONException {
		for (int index = 0; index < jsonArray.length(); index++) {
			JSONObject obj = jsonArray.getJSONObject(index);
			int activityType = obj.getInt("activityType");
			JSONObject entity = obj.getJSONObject("activityEntity");
			RecruiteInfo recruiteInfo = null;
			switch (activityType) {
			case RecruiteInfo.RECRUITE_INFO_TYPE_CAMPUS_TALKING:
				CampusTalking campusTalking = new CampusTalking();
				campusTalking.setAddress(entity.getString("address"));
				campusTalking.setCompanyId(entity.getString("companyId"));
				campusTalking.setCompanyName(entity.getString("companyName"));
				campusTalking.setDate(entity.getString("startDate"));
				campusTalking.setTime(entity.getString("startTime"));
				campusTalking.setId(entity.getString("meetingId"));
				campusTalking.setSchoolId(entity.getString("schoolId"));
				campusTalking.setSchoolName(entity.getString("schoolName"));
				recruiteInfo = campusTalking;
				break;
			case RecruiteInfo.RECRUITE_INFO_TYPE_DAILY_INFO:
				DailyInfo dailyInfo = new DailyInfo();
				dailyInfo.setId(entity.getString("recruitinfoId"));
				dailyInfo.setCompanyId(entity.getString("companyId"));
				dailyInfo.setCompanyName(entity.getString("companyName"));
				dailyInfo.setDetail(entity.getString("detailInfo"));
				dailyInfo.setTitle(entity.getString("title"));
				recruiteInfo = dailyInfo;
				break;
			case RecruiteInfo.RECRUITE_INFO_TYPE_NET_APPLICATION:
				NetApplication netApplication = new NetApplication();
				netApplication.setUrlAddress(entity.getString("urlAddress"));
				netApplication.setCompanyId(entity.getString("companyId"));
				netApplication.setCompanyName(entity.getString("companyName"));
				netApplication.setId(entity.getString("onlineApplicationId"));
				netApplication.setStartDate(entity.getString("startDate"));
				netApplication.setStartTime(entity.getString("startTime"));
				netApplication.setEndDate(entity.getString("endDate"));
				netApplication.setEndTime(entity.getString("endTime"));
				recruiteInfo = netApplication;
				break;
			}
			switch (procedureType) {
			case PROCEDURE_APPLICATED:
				if (cachedApplicatedProcedures == null)
					cachedApplicatedProcedures = new LinkedList<RecruiteInfo>();
				cachedApplicatedProcedures.add(recruiteInfo);
				break;
			case PROCEDURE_REFUSED:
				if (cachedRefusedProcedures == null)
					cachedRefusedProcedures = new LinkedList<RecruiteInfo>();
				cachedRefusedProcedures.add(recruiteInfo);
				break;
			case PROCEDURE_STORED:
				if (cachedStoredProcedures == null)
					cachedStoredProcedures = new LinkedList<RecruiteInfo>();
				cachedStoredProcedures.add(recruiteInfo);
				break;
			}
		}
	}

	public void submitProcedure(String renrenId, String recruiteInfoId,
			String companyId, String recruiteInfoType, int procedureType) {
		Map<String, String> params = new HashMap<String, String>();
		params.put("renrenId", renrenId);
		params.put("companyId", companyId);
		params.put("activityId", recruiteInfoId);
		params.put("activityType", recruiteInfoType);
		params.put("procedureType", String.valueOf(procedureType));
		Connection.getInstance().executeHttpPost(
				Connection.BIZ_SUBMIT_PERSONAL_ACTIVITY, params);
	}
}
